import axios from 'axios';
import { Request } from 'express';

export class IpUtil {
  //get real IP
  public static getRealIP(req: Request) {
    let realIp: string = '';

    if (!realIp || realIp === 'unknown') {
      const xForwardedFor = req.headers['x-forwarded-for'];
      if (xForwardedFor) {
        realIp = Array.isArray(xForwardedFor)
          ? xForwardedFor[0].toLowerCase()
          : xForwardedFor.split(',')[0].trim().toLowerCase();
      }
    }

    if (!realIp || realIp === 'unknown') {
      realIp = ((req.headers['proxy-client-ip'] as string) || '').toLowerCase();
    }

    if (!realIp || realIp === 'unknown') {
      realIp = (
        (req.headers['wl-proxy-client-ip'] as string) || ''
      ).toLowerCase();
    }

    const ip = realIp || req.ip?.replace('::ffff:', '').toLowerCase();

    return ip;
  }

  public static isPrivateIp(ip: string): boolean {
    ip.toLowerCase();
    if (ip === 'localhost') return true;
    let a_ip = 0;
    if (ip === '') return false;
    const aNum = ip.split('.');
    if (aNum.length !== 4) return false;
    a_ip += Number.parseInt(aNum[0]) << 24;
    a_ip += Number.parseInt(aNum[1]) << 16;
    a_ip += Number.parseInt(aNum[2]) << 8;
    a_ip += Number.parseInt(aNum[3]) << 0;
    a_ip = (a_ip >> 16) & 0xffff;
    return (
      a_ip >> 8 === 0x7f ||
      a_ip >> 8 === 0xa ||
      a_ip === 0xc0a8 ||
      (a_ip >= 0xac10 && a_ip <= 0xac1f)
    );
  }
}
/**
 * 获取IP地理位置
 * @param ip ip
 * @returns
 */
export async function getIpAddress(ip: string) {
  if (IpUtil.isPrivateIp(ip)) {
    return '内网IP';
  }
  try {
    let { data } = await axios.get(
      `https://whois.pconline.com.cn/ipJson.jsp?ip=${ip}&json=true`,
      { responseType: 'arraybuffer' },
    );
    data = new TextDecoder('gbk').decode(data);
    data = JSON.parse(data);
    return data.addr.trim().split(' ').at(0);
  } catch {
    return '未知';
  }
}
